home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).bin / DXF / samples / multimedia / dplay / src / duel / gfx.cpp < prev    next >
C/C++ Source or Header  |  1999-04-20  |  16KB  |  535 lines

  1. //-----------------------------------------------------------------------------
  2. // File: gfx.cpp
  3. //
  4. // Desc: Graphics routines
  5. //
  6. // Copyright (C) 1995-1999 Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "duel.h"
  9. #include "gfx.h"
  10. #include "diutil.h"
  11. #include "ddutil.h"
  12.  
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Globals
  16. //-----------------------------------------------------------------------------
  17. extern BOOL             g_bFullscreen;   // Window or fullscreen mode ?
  18. extern HWND             g_hwndMain;      // Main window
  19. extern DWORD            g_dwKeys;               
  20. extern int              g_nProgramState; // Current state of program
  21. extern RECT             g_rcWindow;      // Client window rectangle
  22. extern HINSTANCE        g_hInst;         // Application instance handle
  23.  
  24.  
  25. LPDIRECTDRAW            g_pDD             = NULL; // DirectDraw interface
  26. LPDIRECTDRAWPALETTE     g_pArtPalette     = NULL; // Game screen palette
  27. LPDIRECTDRAWPALETTE     g_pSplashPalette  = NULL; // Splash screen palette
  28. LPDIRECTDRAWSURFACE     g_pddsFrontBuffer = NULL; // primary surface
  29. LPDIRECTDRAWSURFACE     g_pddsBackBuffer  = NULL; // back buffer for animation
  30. LPDIRECTDRAWSURFACE     g_pddsShip[4];            // ship bitmaps
  31. LPDIRECTDRAWSURFACE     g_pddsNumbers;            // Numbers bitmap
  32. DWORD                   g_dwFillColor;
  33.  
  34.  
  35.  
  36.  
  37. //-----------------------------------------------------------------------------
  38. // Name: InitGraphics()
  39. // Desc:
  40. //-----------------------------------------------------------------------------
  41. HRESULT InitGraphics()
  42. {
  43.     DDCAPS          ddcaps;
  44.     HRESULT         hr;
  45.     DDSURFACEDESC   ddsd;
  46.     DDSCAPS         ddscaps;
  47.  
  48.     // Create a window
  49.     g_hwndMain = CreateWindowEx( WS_EX_APPWINDOW, TEXT("DuelClass"),
  50.                                  TEXT("Duel"), WS_POPUP | WS_SYSMENU, 0, 0, 
  51.                                  GetSystemMetrics(SM_CXSCREEN),
  52.                                  GetSystemMetrics(SM_CYSCREEN),
  53.                                  NULL, NULL, g_hInst, NULL );
  54.     if( NULL == g_hwndMain )
  55.         return E_FAIL;
  56.  
  57.     UpdateWindow( g_hwndMain );
  58.     SetFocus( g_hwndMain );
  59.  
  60.     // DDraw stuff begins here
  61.     if( FAILED( hr = DirectDrawCreate( NULL, &g_pDD, NULL ) ) )
  62.     {
  63.         ShowError(IDS_DDRAW_ERROR_DDC);
  64.         return E_FAIL;
  65.     }
  66.  
  67.     // Set access mode based on fullscreen/window
  68.     if( g_bFullscreen ) 
  69.     {
  70.         hr = g_pDD->SetCooperativeLevel( g_hwndMain,
  71.                             DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  72.     }
  73.     else
  74.     {
  75.         hr = g_pDD->SetCooperativeLevel( g_hwndMain,
  76.                             DDSCL_NORMAL);
  77.     }
  78.  
  79.     if( FAILED(hr) )
  80.     {
  81.         ShowError(IDS_DDRAW_ERROR_SCL);
  82.         return E_FAIL;
  83.     }
  84.  
  85.     if( g_bFullscreen )
  86.     {
  87.         // Set the mode to 640 by 480 by 8
  88.         if( FAILED( g_pDD->SetDisplayMode( 640, 480, 8 ) ) )
  89.         {
  90.             ShowError(IDS_DDRAW_ERROR_SDM);
  91.             return E_FAIL;
  92.         }
  93.     }
  94.     else
  95.     {
  96.         RECT  rcWork;
  97.         RECT  rc;
  98.         DWORD dwStyle;
  99.  
  100.         // If we are still a WS_POPUP window we should convert to a
  101.         // normal app window so we look like a windows app.
  102.         dwStyle  = GetWindowStyle(g_hwndMain);
  103.         dwStyle &= ~WS_POPUP;
  104.         dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
  105.         SetWindowLong( g_hwndMain, GWL_STYLE, dwStyle );
  106.  
  107.         // Aet window size
  108.         SetRect( &rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y );
  109.  
  110.         AdjustWindowRectEx( &rc, GetWindowStyle(g_hwndMain),
  111.                             GetMenu(g_hwndMain) != NULL,
  112.                             GetWindowExStyle(g_hwndMain) );
  113.  
  114.         SetWindowPos( g_hwndMain, NULL, 0, 0, rc.right-rc.left,
  115.                       rc.bottom-rc.top,
  116.                       SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  117.  
  118.         SetWindowPos( g_hwndMain, HWND_NOTOPMOST, 0, 0, 0, 0,
  119.                       SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  120.  
  121.         //  Make sure our window does not hang outside of the work area
  122.         SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
  123.         GetWindowRect( g_hwndMain, &rc );
  124.         if( rc.left < rcWork.left ) rc.left = rcWork.left;
  125.         if( rc.top  < rcWork.top )  rc.top  = rcWork.top;
  126.         SetWindowPos( g_hwndMain, NULL, rc.left, rc.top, 0, 0,
  127.                       SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
  128.     }
  129.  
  130.     // Check the color key hardware capabilities
  131.     ddcaps.dwSize = sizeof( ddcaps );
  132.     memset( &ddsd, 0, sizeof( ddsd ) );
  133.     ddsd.dwSize = sizeof( ddsd );
  134.  
  135.     if( g_bFullscreen )
  136.     {
  137.         // Create surfaces
  138.         ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  139.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  140.                               DDSCAPS_FLIP |
  141.                               DDSCAPS_COMPLEX;
  142.         ddsd.dwBackBufferCount = 1;
  143.         if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer,
  144.                                                NULL ) ) )
  145.         {
  146.             ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
  147.             return E_FAIL;
  148.         }
  149.  
  150.         // Get a pointer to the back buffer
  151.         ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  152.         if( FAILED( hr = g_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
  153.                                                          &g_pddsBackBuffer ) ) )
  154.         {
  155.             ShowError(IDS_DDRAW_ERROR_GAS);
  156.             return E_FAIL;
  157.         }
  158.     }
  159.     else
  160.     {
  161.         LPDIRECTDRAWCLIPPER pcClipper;
  162.         
  163.         // Window case, create the primary surface
  164.         // and create a backbuffer in offscreen memory
  165.         ddsd.dwFlags = DDSD_CAPS;
  166.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  167.  
  168.         if( FAILED( g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer, NULL ) ) )
  169.         {
  170.             ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
  171.             return E_FAIL;
  172.         }
  173.  
  174.         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
  175.         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  176.         ddsd.dwWidth = MAX_DEFWIN_X;
  177.         ddsd.dwHeight = MAX_DEFWIN_Y;
  178.         if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL ) ) )
  179.         {
  180.             ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
  181.             return E_FAIL;
  182.         }
  183.  
  184.         if( FAILED( hr = g_pDD->CreateClipper( 0, &pcClipper, NULL) ) )
  185.         {
  186.             ShowError(IDS_DDRAW_ERROR_CC);
  187.             return E_FAIL;
  188.         }
  189.  
  190.         if( FAILED( hr = pcClipper->SetHWnd( 0, g_hwndMain) ) )
  191.         {
  192.             pcClipper->Release();
  193.             ShowError(IDS_DDRAW_ERROR_SH);
  194.             return E_FAIL;
  195.         }
  196.  
  197.         if( FAILED( hr = g_pddsFrontBuffer->SetClipper( pcClipper) ) )
  198.         {
  199.             pcClipper->Release();
  200.             ShowError(IDS_DDRAW_ERROR_SC);
  201.             return E_FAIL;
  202.         }
  203.  
  204.         // Done with clipper
  205.         pcClipper->Release();
  206.     }
  207.  
  208.     ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; 
  209.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  210.  
  211.     ddsd.dwWidth  = 320;
  212.     ddsd.dwHeight = 128;
  213.     
  214.     for( DWORD i=0; i<4; i++ )
  215.     {
  216.         if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsShip[i], NULL ) ) )
  217.         {
  218.             ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
  219.             return E_FAIL;
  220.         }   
  221.     }
  222.  
  223.     ddsd.dwHeight = 16;
  224.     if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsNumbers, NULL ) ) )
  225.     {
  226.         ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
  227.         return E_FAIL;
  228.     }
  229.  
  230.     if( FAILED( RestoreSurfaces() ) )
  231.     {
  232.         ShowError(IDS_DDRAW_ERROR_RS);
  233.         return E_FAIL;
  234.     }
  235.     
  236.     g_dwKeys = 0;
  237.     ShowWindow( g_hwndMain, SW_SHOW);
  238.     return S_OK;
  239. }
  240.  
  241.  
  242.  
  243.  
  244. //-----------------------------------------------------------------------------
  245. // Name: CleanupGraphics()
  246. // Desc:
  247. //-----------------------------------------------------------------------------
  248. VOID CleanupGraphics()
  249. {
  250.     for( DWORD i=0; i<4; i++ )
  251.         if( g_pddsShip[i] )
  252.             g_pddsShip[i]->Release();
  253.     if( g_pddsNumbers )
  254.         g_pddsNumbers->Release();
  255.     if( g_pddsFrontBuffer )
  256.         g_pddsFrontBuffer->Release();
  257.     if( g_pArtPalette )
  258.         g_pArtPalette->Release();
  259.     if( g_pSplashPalette )
  260.         g_pSplashPalette->Release();
  261.     if( !g_bFullscreen && g_pddsBackBuffer )
  262.         g_pddsBackBuffer->Release();
  263.     if( g_pDD )
  264.         g_pDD->Release();
  265. }
  266.  
  267.  
  268.  
  269.  
  270. //-----------------------------------------------------------------------------
  271. // Name: BltSplashScreen()
  272. // Desc:
  273. //-----------------------------------------------------------------------------
  274. HRESULT BltSplashScreen( RECT* prc )
  275. {
  276.     HRESULT hr;
  277.     HBITMAP hbm;
  278.  
  279.     if( ( g_pddsFrontBuffer == NULL ) || ( g_pSplashPalette == NULL ) ||
  280.         ( g_pddsBackBuffer == NULL ) )
  281.         return E_FAIL;
  282.  
  283.     // Set the palette before loading the splash screen
  284.     g_pddsFrontBuffer->SetPalette( g_pSplashPalette );
  285.  
  286.     hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), TEXT("SPLASH"),
  287.                               IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
  288.     if( NULL == hbm )
  289.         return E_FAIL;
  290.     
  291.     // If the surface is lost, DDUtil_CopyBitmap will fail and the surface will
  292.     // be restored below.
  293.     hr = DDUtil_CopyBitmap( g_pddsBackBuffer, hbm, 0, 0, 0, 0 );
  294.  
  295.     DeleteObject( hbm );
  296.  
  297.     while( 1 )
  298.     {
  299.         hr = g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer,
  300.                                      prc, DDBLT_WAIT, NULL);
  301.         if( SUCCEEDED(hr) )
  302.             return S_OK;
  303.         if( hr == DDERR_SURFACELOST )
  304.             if( FAILED( RestoreSurfaces() ) )
  305.                 return E_FAIL;
  306.         if( hr != DDERR_WASSTILLDRAWING )
  307.             return E_FAIL;
  308.     }
  309. }
  310.  
  311.  
  312.  
  313.  
  314. //-----------------------------------------------------------------------------
  315. // Name: BltNumber()
  316. // Desc:
  317. //-----------------------------------------------------------------------------
  318. HRESULT BltNumber( CHAR* strScore, int x, int y )
  319. {
  320.     while( *strScore )
  321.     {
  322.         RECT src;
  323.         src.left   = ((*strScore++)-'0')*16;
  324.         src.top    = 0;
  325.         src.right  = src.left + 16;
  326.         src.bottom = src.top + 16;
  327.  
  328.         BltObject( x, y, g_pddsNumbers, &src, DDBLTFAST_SRCCOLORKEY );
  329.         x += 16;
  330.     }
  331.  
  332.     return S_OK;
  333. }
  334.  
  335.  
  336.  
  337.  
  338. //-----------------------------------------------------------------------------
  339. // Name: BltObject()
  340. // Desc: 
  341. //-----------------------------------------------------------------------------
  342. HRESULT BltObject( int x, int y, LPDIRECTDRAWSURFACE pdds, RECT* prc,
  343.                    DWORD flags )
  344. {
  345.     if( NULL == pdds )
  346.         return E_FAIL;
  347.     
  348.     while( 1 )
  349.     {
  350.         HRESULT hr = g_pddsBackBuffer->BltFast( x, y, pdds, prc, flags );
  351.         if( FAILED(hr) )
  352.         {
  353.             if( hr == DDERR_WASSTILLDRAWING )
  354.                 continue;
  355.  
  356.             if( hr == DDERR_SURFACELOST )
  357.                 if( SUCCEEDED( RestoreSurfaces() ) )
  358.                     continue;
  359.             return E_FAIL;
  360.         }
  361.  
  362.         return S_OK;
  363.     }
  364. }
  365.  
  366.  
  367.  
  368.  
  369. //-----------------------------------------------------------------------------
  370. // Name: EraseScreen()
  371. // Desc: 
  372. //-----------------------------------------------------------------------------
  373. VOID EraseScreen()
  374. {
  375.     // Erase the background
  376.     DDBLTFX ddbltfx;
  377.     ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
  378.     ddbltfx.dwSize = sizeof(ddbltfx);
  379. #ifdef NONAMELESSUNION
  380.     ddbltfx.u5.dwFillColor = g_dwFillColor;
  381. #else
  382.     ddbltfx.dwFillColor = g_dwFillColor;
  383. #endif
  384.  
  385.     while( 1 )
  386.     {
  387.         HRESULT hr = g_pddsBackBuffer->Blt( NULL, NULL, NULL,
  388.                                             DDBLT_COLORFILL, &ddbltfx );
  389.         if( SUCCEEDED(hr) )
  390.             return;
  391.         
  392.         if( hr == DDERR_SURFACELOST )
  393.         {
  394.             if( FAILED( RestoreSurfaces() ) )
  395.                 return;
  396.         }
  397.  
  398.         if( hr != DDERR_WASSTILLDRAWING )
  399.             return;
  400.     }
  401. }
  402.  
  403.  
  404.  
  405.  
  406. //-----------------------------------------------------------------------------
  407. // Name: FlipScreen()
  408. // Desc: 
  409. //-----------------------------------------------------------------------------
  410. VOID FlipScreen()
  411. {
  412.     // Flip the surfaces
  413.     if( g_bFullscreen )
  414.     {
  415.         while( 1 )
  416.         {
  417.             HRESULT hr = g_pddsFrontBuffer->Flip( NULL, 0 );
  418.  
  419.             if( hr == DDERR_SURFACELOST )
  420.             {
  421.                 if( FAILED( RestoreSurfaces() ) )
  422.                     return;
  423.             }
  424.             if( hr != DDERR_WASSTILLDRAWING )
  425.                     return;
  426.         }
  427.     }
  428.     else
  429.     {
  430.         g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer, NULL,
  431.                                 DDBLT_WAIT, NULL );
  432.     }
  433. }
  434.  
  435.  
  436.  
  437.  
  438.  
  439. //-----------------------------------------------------------------------------
  440. // Name: RestoreSurfaces()
  441. // Desc:
  442. //-----------------------------------------------------------------------------
  443. HRESULT RestoreSurfaces()
  444. {
  445.     HRESULT hr;
  446.     HBITMAP hbm;
  447.  
  448.     if( FAILED( hr = g_pddsFrontBuffer->Restore() ) )
  449.         return hr;
  450.     if( FAILED( hr = g_pddsBackBuffer->Restore() ) )
  451.         return hr;
  452.  
  453.     for( DWORD i=0; i<4; i++ )
  454.         if( FAILED( hr = g_pddsShip[i]->Restore() ) )
  455.             return hr;
  456.  
  457.     // Create and set the palette for the splash bitmap
  458.     g_pSplashPalette = DDUtil_LoadPalette( g_pDD, TEXT("SPLASH") );
  459.     if( NULL == g_pSplashPalette )
  460.         return E_FAIL;
  461.  
  462.     // Create and set the palette for the art bitmap
  463.     g_pArtPalette = DDUtil_LoadPalette( g_pDD, TEXT("Duel8") );
  464.     if( NULL == g_pArtPalette )
  465.         return E_FAIL;
  466.  
  467.     // set the palette before loading the art
  468.     g_pddsFrontBuffer->SetPalette( g_pArtPalette );
  469.  
  470.     hbm = (HBITMAP)LoadImage( GetModuleHandle(NULL), TEXT("Duel8"),
  471.                               IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
  472.     if( NULL == hbm )
  473.         return E_FAIL;
  474.  
  475.     if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[0], hbm, 0, 0, 320, 128 ) ) )
  476.     {
  477.         DeleteObject( hbm );
  478.         return E_FAIL;
  479.     }
  480.  
  481.     if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[1], hbm, 0, 128, 320, 128 ) ) )
  482.     {
  483.         DeleteObject( hbm );
  484.         return E_FAIL;
  485.     }
  486.  
  487.     if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[2], hbm, 0, 256, 320, 128 ) ) )
  488.     {
  489.         DeleteObject( hbm );
  490.         return E_FAIL;
  491.     }
  492.  
  493.     if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[3], hbm, 0, 384, 320, 128 ) ) )
  494.     {
  495.         DeleteObject( hbm );
  496.         return E_FAIL;
  497.     }
  498.  
  499.     if( FAILED( hr = DDUtil_CopyBitmap( g_pddsNumbers, hbm, 0, 512, 320, 16 ) ) )
  500.     {
  501.         DeleteObject( hbm );
  502.         return E_FAIL;
  503.     }
  504.  
  505.     DeleteObject( hbm );
  506.  
  507.     // set colorfill colors and colorkeys according to bitmap contents
  508.     g_dwFillColor = DDUtil_ColorMatch( g_pddsShip[0], CLR_INVALID );
  509.     
  510.     DDUtil_SetColorKey( g_pddsShip[0], CLR_INVALID );
  511.     DDUtil_SetColorKey( g_pddsShip[1], CLR_INVALID );
  512.     DDUtil_SetColorKey( g_pddsShip[2], CLR_INVALID );
  513.     DDUtil_SetColorKey( g_pddsShip[3], CLR_INVALID );
  514.     DDUtil_SetColorKey( g_pddsNumbers, CLR_INVALID );
  515.  
  516.     return S_OK;
  517. }
  518.  
  519.  
  520.  
  521.  
  522. //-----------------------------------------------------------------------------
  523. // Name: SetGamePalette()
  524. // Desc:
  525. //-----------------------------------------------------------------------------
  526. VOID SetGamePalette()
  527. {
  528.     if( g_pddsFrontBuffer )
  529.         g_pddsFrontBuffer->SetPalette( g_pArtPalette );
  530. }
  531.  
  532.  
  533.  
  534.  
  535.